μ€μ©μ μΈ μμλ₯Ό ν΅ν΄ JavaScript ν΄λ‘μ λ₯Ό μ΄ν΄λ³΄κ³ , ν΄λ‘μ μ κΈ°λ₯κ³Ό μννΈμ¨μ΄ κ°λ°μμμ μ€μ μ μ© μ¬λ‘λ₯Ό μμ보μΈμ.
JavaScript ν΄λ‘μ : μ€μ©μ μΈ μμλ‘ μ΄ν΄νκΈ°
ν΄λ‘μ λ λͺ¨λ μμ€μ κ°λ°μμκ² νΌλμ μΌκΈ°νλ κ²½μ°κ° λ§μ JavaScriptμ κΈ°λ³Έ κ°λ μ λλ€. ν΄λ‘μ λ₯Ό μ΄ν΄νλ κ²μ ν¨μ¨μ μ΄κ³ , μ μ§ κ΄λ¦¬ κ°λ₯νλ©°, μμ ν μ½λλ₯Ό μμ±νλ λ° λ§€μ° μ€μν©λλ€. μ΄ ν¬κ΄μ μΈ κ°μ΄λλ μ€μ©μ μΈ μμλ₯Ό ν΅ν΄ ν΄λ‘μ λ₯Ό λͺ νν μ€λͺ νκ³ μ€μ μ μ© μ¬λ‘λ₯Ό 보μ¬μ€λλ€.
ν΄λ‘μ λ 무μμΈκ°?
κ°λ¨ν λ§ν΄μ, ν΄λ‘μ λ ν¨μμ ν΄λΉ ν¨μκ° μ μΈλ μ΄νμ νκ²½μ μ‘°ν©μ λλ€. μ¦, ν΄λ‘μ λ₯Ό μ¬μ©νλ©΄ μΈλΆ ν¨μκ° μ€νμ μλ£ν νμλ ν¨μκ° μ£Όλ³ μ€μ½νμ λ³μμ μ‘μΈμ€ν μ μμ΅λλ€. λ΄λΆ ν¨μκ° ν΄λΉ νκ²½μ "κΈ°μ΅"νλ€κ³ μκ°νλ©΄ λ©λλ€.
μ΄κ²μ μ§μ μΌλ‘ μ΄ν΄νλ €λ©΄ ν΅μ¬ κ΅¬μ± μμλ₯Ό λΆμν΄ λ³΄κ² μ΅λλ€.
- ν¨μ: ν΄λ‘μ μ μΌλΆλ₯Ό νμ±νλ λ΄λΆ ν¨μμ λλ€.
- μ΄νμ νκ²½: ν¨μκ° μ μΈλ μ£Όλ³ μ€μ½νμ λλ€. μ¬κΈ°μλ λ³μ, ν¨μ λ° κΈ°ν μ μΈμ΄ ν¬ν¨λ©λλ€.
λ΄λΆ ν¨μκ° μΈλΆ ν¨μκ° λ°νλ νμλ ν΄λΉ μ΄νμ μ€μ½νμ λ³μμ λν μ‘μΈμ€λ₯Ό μ μ§νκΈ° λλ¬Έμ λ§λ²μ΄ μΌμ΄λ©λλ€. μ΄ λμμ JavaScriptκ° μ€μ½νμ λ©λͺ¨λ¦¬ κ΄λ¦¬λ₯Ό μ²λ¦¬νλ λ°©μμ ν΅μ¬ λΆλΆμ λλ€.
ν΄λ‘μ κ° μ€μν μ΄μ λ 무μμΈκ°?
ν΄λ‘μ λ λ¨μν μ΄λ‘ μ κ°λ μ΄ μλλΌ JavaScriptμμ λ§μ μΌλ°μ μΈ νλ‘κ·Έλλ° ν¨ν΄μ νμμ μ λλ€. λ€μκ³Ό κ°μ μ΄μ μ μ 곡ν©λλ€.
- λ°μ΄ν° μΊ‘μν: ν΄λ‘μ λ₯Ό μ¬μ©νλ©΄ κ°μΈ λ³μμ λ©μλλ₯Ό μμ±νμ¬ μΈλΆ μ‘μΈμ€ λ° μμ μΌλ‘λΆν° λ°μ΄ν°λ₯Ό 보νΈν μ μμ΅λλ€.
- μν 보쑴: ν΄λ‘μ λ ν¨μ νΈμΆ κ° λ³μμ μνλ₯Ό μ μ§νλ©°, μΉ΄μ΄ν°, νμ΄λ¨Έ λ° κΈ°ν μν μ μ₯ κ΅¬μ± μμλ₯Ό λ§λλ λ° μ μ©ν©λλ€.
- κ³ μ°¨ ν¨μ: ν΄λ‘μ λ μ’ μ’ κ³ μ°¨ ν¨μ(λ€λ₯Έ ν¨μλ₯Ό μΈμλ‘ μ¬μ©νκ±°λ ν¨μλ₯Ό λ°ννλ ν¨μ)μ ν¨κ» μ¬μ©λμ΄ κ°λ ₯νκ³ μ μ°ν μ½λλ₯Ό κ°λ₯νκ² ν©λλ€.
- λΉλκΈ° JavaScript: ν΄λ‘μ λ μ½λ°± λ° νλ‘λ―Έμ€μ κ°μ λΉλκΈ° μμ μ κ΄λ¦¬νλ λ° μ€μν μν μ ν©λλ€.
JavaScript ν΄λ‘μ μ μ€μ©μ μΈ μμ
ν΄λ‘μ κ° μ΄λ»κ² μλνκ³ μ€μ μλ리μ€μμ μ΄λ»κ² μ¬μ©ν μ μλμ§ μ€λͺ νκΈ° μν΄ λͺ κ°μ§ μ€μ©μ μΈ μμλ₯Ό μ΄ν΄λ³΄κ² μ΅λλ€.
μμ 1: κ°λ¨ν μΉ΄μ΄ν°
μ΄ μμλ ν΄λ‘μ λ₯Ό μ¬μ©νμ¬ ν¨μ νΈμΆ κ°μ μνλ₯Ό μ μ§νλ μΉ΄μ΄ν°λ₯Ό λ§λλ λ°©λ²μ 보μ¬μ€λλ€.
function createCounter() {
let count = 0;
return function() {
count++;
console.log(count);
};
}
const increment = createCounter();
increment(); // Output: 1
increment(); // Output: 2
increment(); // Output: 3
μ€λͺ :
createCounter()λ λ³μcountλ₯Ό μ μΈνλ μΈλΆ ν¨μμ λλ€.countλ₯Ό μ¦κ°μν€κ³ ν΄λΉ κ°μ λ‘κΉ νλ λ΄λΆ ν¨μ(μ΄ κ²½μ° μ΅λͺ ν¨μ)λ₯Ό λ°νν©λλ€.- λ΄λΆ ν¨μλ
countλ³μμ λν ν΄λ‘μ λ₯Ό νμ±ν©λλ€. createCounter()κ° μ€νμ μλ£ν νμλ λ΄λΆ ν¨μλcountλ³μμ λν μ‘μΈμ€λ₯Ό μ μ§ν©λλ€.increment()μ λν κ° νΈμΆμ λμΌνcountλ³μλ₯Ό μ¦κ°μμΌ ν΄λ‘μ κ° μνλ₯Ό 보쑴νλ κΈ°λ₯μ 보μ¬μ€λλ€.
μμ 2: κ°μΈ λ³μλ₯Ό μ¬μ©ν λ°μ΄ν° μΊ‘μν
ν΄λ‘μ λ₯Ό μ¬μ©νμ¬ κ°μΈ λ³μλ₯Ό μμ±νμ¬ ν¨μ μΈλΆμμ μ§μ μ‘μΈμ€νκ³ μμ νλ κ²μ λ°©μ§ν μ μμ΅λλ€.
function createBankAccount(initialBalance) {
let balance = initialBalance;
return {
deposit: function(amount) {
balance += amount;
return balance; //Returning for demonstration, could be void
},
withdraw: function(amount) {
if (amount <= balance) {
balance -= amount;
return balance; //Returning for demonstration, could be void
} else {
return "Insufficient funds.";
}
},
getBalance: function() {
return balance;
}
};
}
const account = createBankAccount(1000);
console.log(account.deposit(500)); // Output: 1500
console.log(account.withdraw(200)); // Output: 1300
console.log(account.getBalance()); // Output: 1300
// Trying to access balance directly will not work
// console.log(account.balance); // Output: undefined
μ€λͺ :
createBankAccount()λ μ κΈ, μΆκΈ λ° μμ‘μ κ°μ Έμ€λ λ©μλκ° μλ μν κ³μ’ κ°μ²΄λ₯Ό μμ±ν©λλ€.balanceλ³μλcreateBankAccount()μ μ€μ½ν λ΄μμ μ μΈλλ©° μΈλΆμμ μ§μ μ‘μΈμ€ν μ μμ΅λλ€.deposit,withdrawλ°getBalanceλ©μλλbalanceλ³μμ λν ν΄λ‘μ λ₯Ό νμ±ν©λλ€.- μ΄λ¬ν λ©μλλ
balanceλ³μμ μ‘μΈμ€νμ¬ μμ ν μ μμ§λ§ λ³μ μ체λ λΉκ³΅κ°λ‘ μ μ§λ©λλ€.
μμ 3: 루νμμ `setTimeout`κ³Ό ν¨κ» ν΄λ‘μ μ¬μ©νκΈ°
ν΄λ‘μ λ νΉν 루ν λ΄μμ setTimeoutκ³Ό κ°μ λΉλκΈ° μμ
μΌλ‘ μμ
ν λ νμμ μ
λλ€. ν΄λ‘μ κ° μμΌλ©΄ JavaScriptμ λΉλκΈ° νΉμ±μΌλ‘ μΈν΄ μκΈ°μΉ μμ λμμ΄ λ°μν μ μμ΅λλ€.
for (var i = 1; i <= 5; i++) {
(function(j) {
setTimeout(function() {
console.log("Value of i: " + j);
}, j * 1000);
})(i);
}
// Output:
// Value of i: 1 (after 1 second)
// Value of i: 2 (after 2 seconds)
// Value of i: 3 (after 3 seconds)
// Value of i: 4 (after 4 seconds)
// Value of i: 5 (after 5 seconds)
μ€λͺ :
- ν΄λ‘μ (μ¦μ νΈμΆ ν¨μ ννμ λλ IIFE)κ° μμΌλ©΄ λͺ¨λ
setTimeoutμ½λ°±μ΄ κ²°κ΅ λ£¨νκ° μλ£λ ν μ΅μ’ κ°μ΄ 6μ΄ λλ λμΌνiλ³μλ₯Ό μ°Έμ‘°ν©λλ€. - IIFEλ 루νμ κ° λ°λ³΅μ λν΄ μ μ€μ½νλ₯Ό μμ±νμ¬
jλ§€κ°λ³μμiμ νμ¬ κ°μ μΊ‘μ²ν©λλ€. - κ°
setTimeoutμ½λ°±μjλ³μμ λν ν΄λ‘μ λ₯Ό νμ±νμ¬ κ° λ°λ³΅μ λν΄iμ μ¬λ°λ₯Έ κ°μ λ‘κΉ ν©λλ€.
루νμμ var λμ letμ μ¬μ©ν΄λ μ΄ λ¬Έμ κ° ν΄κ²°λλ©°, letμ κ° λ°λ³΅μ λν΄ λΈλ‘ μ€μ½νλ₯Ό μμ±ν©λλ€.
for (let i = 1; i <= 5; i++) {
setTimeout(function() {
console.log("Value of i: " + i);
}, i * 1000);
}
// Output (same as above):
// Value of i: 1 (after 1 second)
// Value of i: 2 (after 2 seconds)
// Value of i: 3 (after 3 seconds)
// Value of i: 4 (after 4 seconds)
// Value of i: 5 (after 5 seconds)
μμ 4: μ»€λ§ λ° λΆλΆ μ μ©
ν΄λ‘μ λ μ¬λ¬ μΈμλ₯Ό μ¬μ©νλ ν¨μλ₯Ό κ°κ° λ¨μΌ μΈμλ₯Ό μ¬μ©νλ ν¨μμ μνμ€λ‘ λ³ννλ λ° μ¬μ©λλ κΈ°μ μΈ μ»€λ§ λ° λΆλΆ μ μ©μ κΈ°λ³Έμ λλ€.
function multiply(a) {
return function(b) {
return function(c) {
return a * b * c;
};
};
}
const multiplyBy5 = multiply(5);
const multiplyBy5And2 = multiplyBy5(2);
console.log(multiplyBy5And2(3)); // Output: 30 (5 * 2 * 3)
μ€λͺ :
multiplyλ ν λ²μ μΈ κ°μ μΈμλ₯Ό μ¬μ©νλ 컀λ§λ ν¨μμ λλ€.- κ° λ΄λΆ ν¨μλ μΈλΆ μ€μ½ν(
a,b)μ λ³μμ λν ν΄λ‘μ λ₯Ό νμ±ν©λλ€. multiplyBy5λ μ΄λ―Έaλ₯Ό 5λ‘ μ€μ ν ν¨μμ λλ€.multiplyBy5And2λ μ΄λ―Έaλ₯Ό 5λ‘ μ€μ νκ³bλ₯Ό 2λ‘ μ€μ ν ν¨μμ λλ€.multiplyBy5And2(3)μ λν μ΅μ’ νΈμΆμ κ³μ°μ μλ£νκ³ κ²°κ³Όλ₯Ό λ°νν©λλ€.
μμ 5: λͺ¨λ ν¨ν΄
ν΄λ‘μ λ JavaScript μ½λλ₯Ό ꡬμ±νκ³ κ΅¬μ‘°ννκ³ , λͺ¨λμ±μ μ΄μ§νκ³ , μ΄λ¦ μΆ©λμ λ°©μ§νλ λ° λμμ΄ λλ λͺ¨λ ν¨ν΄μμ λ리 μ¬μ©λ©λλ€.
const myModule = (function() {
let privateVariable = "Hello, world!";
function privateMethod() {
console.log(privateVariable);
}
return {
publicMethod: function() {
privateMethod();
},
publicProperty: "This is a public property."
};
})();
console.log(myModule.publicProperty); // Output: This is a public property.
myModule.publicMethod(); // Output: Hello, world!
// Trying to access privateVariable or privateMethod directly will not work
// console.log(myModule.privateVariable); // Output: undefined
// myModule.privateMethod(); // Output: TypeError: myModule.privateMethod is not a function
μ€λͺ :
- IIFEλ
privateVariableκ³ΌprivateMethodλ₯Ό μΊ‘μννλ μ μ€μ½νλ₯Ό μμ±ν©λλ€. - λ°νλ κ°μ²΄λ
publicMethodμpublicPropertyλ§ λ ΈμΆν©λλ€. publicMethodλprivateMethodλ°privateVariableμ λν ν΄λ‘μ λ₯Ό νμ±νμ¬ IIFEκ° μ€νλ νμλ μ‘μΈμ€ν μ μμ΅λλ€.- μ΄ ν¨ν΄μ μ€μ λ‘ κ°μΈ λ° κ³΅κ° λ©€λ²κ° μλ λͺ¨λμ μμ±ν©λλ€.
ν΄λ‘μ μ λ©λͺ¨λ¦¬ κ΄λ¦¬
ν΄λ‘μ λ κ°λ ₯νμ§λ§ λ©λͺ¨λ¦¬ κ΄λ¦¬μ λ―ΈμΉλ μ μ¬μ μν₯μ μΈμνλ κ²μ΄ μ€μν©λλ€. ν΄λ‘μ λ μ£Όλ³ μ€μ½νμ λ³μμ λν μ‘μΈμ€λ₯Ό μ μ§νλ―λ‘ λ μ΄μ νμνμ§ μμ κ²½μ° ν΄λΉ λ³μκ° κ°λΉμ§ μμ§λμ§ μλλ‘ ν μ μμ΅λλ€. μ΄λ‘ μΈν΄ μ£Όμν΄μ μ²λ¦¬νμ§ μμΌλ©΄ λ©λͺ¨λ¦¬ λμκ° λ°μν μ μμ΅λλ€.
λ©λͺ¨λ¦¬ λμλ₯Ό λ°©μ§νλ €λ©΄ λ μ΄μ νμνμ§ μμ κ²½μ° ν΄λ‘μ λ΄μ λ³μμ λν λΆνμν μ°Έμ‘°λ₯Ό μ€λ¨ν΄μΌ ν©λλ€. λ³μλ₯Ό nullλ‘ μ€μ νκ±°λ λΆνμν ν΄λ‘μ μμ±μ νΌνλλ‘ μ½λλ₯Ό μ¬κ΅¬μ±νμ¬ μ΄λ₯Ό μνν μ μμ΅λλ€.
νΌν΄μΌ ν μΌλ°μ μΈ ν΄λ‘μ μ€μ
- μ΄νμ μ€μ½ν μμ΄λ²λ¦¬κΈ°: ν΄λ‘μ λ *μμ± λΉμ* νκ²½μ μΊ‘μ²νλ€λ κ²μ νμ κΈ°μ΅νμμμ€. ν΄λ‘μ κ° μμ±λ ν λ³μκ° λ³κ²½λλ©΄ ν΄λ‘μ λ ν΄λΉ λ³κ²½ μ¬νμ λ°μν©λλ€.
- λΆνμν ν΄λ‘μ μμ±: μ±λ₯κ³Ό λ©λͺ¨λ¦¬ μ¬μ©μ μν₯μ λ―ΈμΉ μ μμΌλ―λ‘ νμνμ§ μμ κ²½μ° ν΄λ‘μ μμ±μ νΌνμμμ€.
- λ³μ μ μΆ: ν΄λ‘μ μμ μΊ‘μ²λ λ³μμ μλͺ μ μΌλμ λκ³ λ©λͺ¨λ¦¬ λμλ₯Ό λ°©μ§νκΈ° μν΄ λ μ΄μ νμνμ§ μμ λ ν΄μ νλμ§ νμΈνμμμ€.
κ²°λ‘
JavaScript ν΄λ‘μ λ λͺ¨λ JavaScript κ°λ°μκ° μ΄ν΄ν΄μΌ νλ κ°λ ₯νκ³ νμμ μΈ κ°λ μ λλ€. λ°μ΄ν° μΊ‘μν, μν 보쑴, κ³ μ°¨ ν¨μ λ° λΉλκΈ° νλ‘κ·Έλλ°μ κ°λ₯νκ² ν©λλ€. ν΄λ‘μ μ μλ λ°©μκ³Ό ν¨κ³Όμ μΌλ‘ μ¬μ©νλ λ°©λ²μ μ΄ν΄νλ©΄ λ³΄λ€ ν¨μ¨μ μ΄κ³ , μ μ§ κ΄λ¦¬ κ°λ₯νλ©°, μμ ν μ½λλ₯Ό μμ±ν μ μμ΅λλ€.
μ΄ κ°μ΄λμμλ μ€μ©μ μΈ μμλ₯Ό ν΅ν΄ ν΄λ‘μ μ λν ν¬κ΄μ μΈ κ°μλ₯Ό μ 곡νμ΅λλ€. μ΄λ¬ν μμλ₯Ό μ°μ΅νκ³ μ€νν¨μΌλ‘μ¨ ν΄λ‘μ μ λν μ΄ν΄λ₯Ό λμ΄κ³ λ λ₯μν JavaScript κ°λ°μκ° λ μ μμ΅λλ€.
μΆκ° νμ΅
- Mozilla Developer Network (MDN): ν΄λ‘μ - https://developer.mozilla.org/ko/docs/Web/JavaScript/Closures
- You Don't Know JS: Scope & Closures by Kyle Simpson
- CodePen λ° JSFiddleκ³Ό κ°μ μ¨λΌμΈ μ½λ© νλ«νΌμ νμνμ¬ λ€μν ν΄λ‘μ μμλ₯Ό μ€νν΄ λ³΄μΈμ.